<!--
	Copyright (c) 2011-2012 by MicroStrategy, Inc.  This copyrighted material
	is the confidential, unpublished property of MicroStrategy.  This
	copyright notice and any other copyright notices included in machine
	readable copies must be reproduced on all authorized copies.
-->
<HTML DIR="LTR">

<HEAD>
	<TITLE>'FPWizard8'</TITLE>
	<META NAME="vs_targetSchema" CONTENT="http://schemas.microsoft.com/intellisense/ie5">
	<LINK ID="LINKURL" REL="stylesheet" HREF="../../1033/NewStyles.css">

	<!--  -->
	<!-- The SYMBOL tag is used to set the default values for the user-defined symbols.-->
	<!--  -->

	<SYMBOL NAME='WIZARD_DIALOG_TITLE' TYPE=text VALUE='MicroStrategy Function Plug-in Wizard'></SYMBOL>
	<SYMBOL NAME='SOURCE_FILTER' TYPE=text VALUE='cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx'></SYMBOL>
	<SYMBOL NAME='HEADER_FILTER' TYPE=text VALUE='h;hpp;hxx;hm;inl;inc;xsd'></SYMBOL>
	<SYMBOL NAME='RESOURCE_FILTER' TYPE=text VALUE='rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav'></SYMBOL>
	<SYMBOL NAME='APP_TYPE_SUMMARY' TYPE=text VALUE='//TODO: Application summary'></SYMBOL>
	<SYMBOL NAME='COPYRIGHT_MSG' TYPE=text VALUE='//      Copyright (c) [!output FPYEAR] by MicroStrategy, Inc.  This copyrighted material
//      is the confidential, unpublished property of MicroStrategy.  This
//      copyright notice and any other copyright notices included in machine
//      readable copies must be reproduced on all authorized copies.'></SYMBOL>
</HEAD>

<BODY BGCOLOR="BUTTONFACE" TOPMARGIN="0" LEFTMARGIN="0" RIGHTMARGIN="0" BOTTOMMARGIN="0" ONLOAD="InitDocument(document);" ONKEYDOWN="OnKey();" ONKEYPRESS="OnPress();">

<TABLE CLASS="ONE" HEIGHT="100%" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0">

<COL CLASS="LinkPane"><COL>

  <!--OPEN OF INTRODUCTORY INFORMATION TABLE//-->
  <TR VALIGN="TOP">
	<TD HEIGHT="79" WIDTH="100%" COLSPAN="2">
	 <TABLE CLASS="TWO" BORDER="0" CELLPADDING="0" CELLSPACING="0">
	 <COL WIDTH="12"><COL><COL WIDTH="12">
	  <TR>
	   <TD VALIGN="TOP" HEIGHT="12" WIDTH="12">
	  	&nbsp;
	   </TD>
  
	   <TD VALIGN="TOP" HEIGHT="12">
	  	&nbsp;
	   </TD>
  
	   <TD VALIGN="TOP" HEIGHT="12" WIDTH="12">
	  	&nbsp;
	   </TD>
  
	   <TD CLASS="IMAGE" VALIGN="BOTTOM" WIDTH="110" ROWSPAN="2">
		<DIV CLASS="SMALLA" ID="Layer0">
		 <IMG CLASS="SMALLEST" SRC="../../Images/FPWizard8.jpg" WIDTH="150" HEIGHT="63" ALT="" BORDER="0" style="left: 2px; bottom: -12px">
		</DIV>
	   </TD>

	   <TD VALIGN="TOP" HEIGHT="12" WIDTH="6" ROWSPAN="2">
	  	&nbsp;
	   </TD>
	  </TR>
	 
	  <TR>
	   <TD VALIGN="TOP" HEIGHT="65" WIDTH="12">
	  	&nbsp;
	   </TD>
	  
	   <TD VALIGN="TOP" HEIGHT="65">
		<H4 CLASS="HEAD" ID="HEAD">Welcome to the MicroStrategy Function Plug-in Wizard</H4>
		<P CLASS="SUBHEAD" ID="SUBHEAD">'TODO: Wizard Description.'</P>
	   </TD>
	  
	   <TD VALIGN="TOP" HEIGHT="65" WIDTH="12">
	  	&nbsp;
	   </TD>
	  </TR>
	 
	  <TR>
	   <TD VALIGN="TOP" CLASS="RULE" COLSPAN="5" HEIGHT="2">
		<TABLE BORDER="0" WIDTH="100%" HEIGHT="1" CELLPADDING="0" CELLSPACING="0">
	  	 <TR VALIGN="TOP">
	  	  <TD HEIGHT="1" WIDTH="100%" BGCOLOR="BUTTONSHADOW"><IMG SRC="../../Images/spacer.gif" HEIGHT="1" WIDTH="1" ALT=""></TD>
	  	  <TD HEIGHT="1" WIDTH="1" BGCOLOR="WINDOW"><IMG SRC="../../Images/spacer.gif" HEIGHT="1" WIDTH="1" ALT=""></TD>
	  	 </TR>
		</TABLE>
	   </TD>
	  </TR>
	 </TABLE>
	</TD>
  </TR>
  <!--CLOSE OF INTRODUCTORY INFORMATION TABLE//-->

  <!--OPEN OF NAVIGATION, CONTENT, AND BUTTON TABLES//-->
  <TR VALIGN="TOP">
	<TD CLASS="Three" VALIGN="TOP" HEIGHT="100%" WIDTH="100%">

	   <!--OPEN OF NAVIGATION TABLE//-->

	    <TABLE CLASS="THREE" BORDER="0" CELLPADDING="0" CELLSPACING="0">
		<COL WIDTH="12"><COL><COL WIDTH="1">
		 <TR>
	   	  <TD VALIGN="TOP" COLSPAN="3" HEIGHT="12">
	  		&nbsp;
		  </TD>
		 </TR>
		 <TR>
	   	  <TD VALIGN="TOP" HEIGHT="100%">
	  		&nbsp;
		  </TD>
	   	  <TD VALIGN="TOP" HEIGHT="100%">

	   	  <!--OPEN OF NAVIGATIONAL LINKS//-->


		  	<DIV CLASS="LINKSELECTED">
	 	   	 <SPAN CLASS="VERTLINE1">
			  <IMG SRC="../../Images/spacer.gif" WIDTH="1" HEIGHT="1" ALT="" BORDER="0">
			 </SPAN>
			 <SPAN CLASS="HORILINE1">
			  <TABLE WIDTH="167" HEIGHT="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0">
			   <TR VALIGN="TOP">
			    <TD CLASS="DOTTEDLINE" HEIGHT="1">
				</TD>
			   </TR>
			   <TR VALIGN="TOP">
			    <TD HEIGHT="100%">
				 <IMG SRC="../../Images/spacer.gif" WIDTH="1" HEIGHT="28" ALT="" BORDER="0">
			    </TD>
			   </TR>
			   <TR VALIGN="TOP">
			    <TD CLASS="DOTTEDLINE" HEIGHT="1">
			    </TD>
			   </TR>
			  </TABLE>
			 </SPAN>

			 <TABLE WIDTH="160" HEIGHT="28" BORDER="0" CELLPADDING="0" CELLSPACING="0" CLASS="LINKTEXTSELECTED">
			  <TR VALIGN="MIDDLE">
			   <TD WIDTH="100%">
				<SPAN ID="Default" TITLE="" onClick="Next(document, 'default.htm');" TABINDEX="1">Page 1</SPAN>
			   </TD>
			   <TD WIDTH="4">
				<IMG SRC="../../Images/spacer.gif" HEIGHT="1" WIDTH="4">
			   </TD>
			  </TR>
			 </TABLE>
			</DIV>
			
	   	  <!--CLOSE OF NAVIGATIONAL LINKS//-->
		  </TD>
		  <TD WIDTH="1">
		   <DIV CLASS="VERTLINE">
			 <IMG SRC="../../Images/spacer.gif" WIDTH="1" HEIGHT="1" ALT="" BORDER="0">
		   </DIV>
		  </TD>
		 </TR>
		</TABLE>
			
	   <!--CLOSE OF NAVIGATION TABLE//-->
	   </TD>
  
	   <TD VALIGN="TOP" HEIGHT="100%">
	   <!--OPEN OF CONTENT AND BUTTON TABLE//-->
	   
	   	<TABLE CLASS="ONE" BORDER="0" CELLPADDING="0" CELLSPACING="0">
		<COL WIDTH="100%">
		 <TR VALIGN="TOP">
		  <TD HEIGHT="100%">
	   	  <!--OPEN OF CONTENT//-->
		  
		  	<TABLE CLASS="CONTENT" BORDER="0" CELLPADDING="0" CELLSPACING="0">
			<COL WIDTH="12"><COL WIDTH="185"><COL WIDTH="12"><COL WIDTH="185"><COL WIDTH="12"><COL WIDTH="185"><COL WIDTH="12">
 			 <TR>
  			  <TD VALIGN="TOP" HEIGHT="12" COLSPAN="5">
  				&nbsp;
  			  </TD>
 			 </TR>
		 	 <TR VALIGN="TOP">
 			 <TD VALIGN="TOP" style="width: 12px; height: 244px">
  				&nbsp;
  			  </TD>
  			  <TD VALIGN="TOP" COLSPAN="3" style="height: 244px; width: 185px;">
 				<SPAN CLASS="itemTextTop">
                     &nbsp;<br />
                     <br />
                     <div style="WIDTH: 96px; POSITION: absolute; HEIGHT: 15px; z-index: 101; left: 0px; top: 8px;" id="lblLibDesc" ondblclick="return lblLibDesc_ondblclick()">Library Description:</div>
                     <div style="WIDTH: 112px; POSITION: absolute; HEIGHT: 15px; z-index: 102; left: 0px; top: 56px;" id="lblFuncInfo">Function Information:</div>
                     &nbsp;<br />
                     <input id="btnFuncScDown" style="z-index: 109; left: 70px; width: 24px; position: absolute;
                         top: 133px" type="button" value="v" onclick="return btnFuncScDown_onclick()" tabindex="6" />
                     <br />
                     &nbsp; &nbsp;<br />
                     &nbsp;<br />
                     &nbsp; &nbsp; &nbsp; &nbsp; 
                     <input id="btnAddFunc" style="z-index: 105; left: 0px; position: absolute; top: 85px; width: 60px;"
                         type="button" value="Add" onclick="return btnAddFunc_onclick()" tabindex="2" accesskey="A" />
                     &nbsp;&nbsp;<br />
                     <br />
                     <input id="btnEditFunc" style="z-index: 106; left: 0px; width: 60px; position: absolute;
                         top: 117px" type="button" value="Edit" onclick="return btnEditFunc_onclick()" tabindex="3" accesskey="E" />
                     <input id="btnDelFunc" style="z-index: 107; left: 0px; position: absolute; top: 149px; width: 60px;"
                         type="button" value="Delete" onclick="return btnDelFunc_onclick()" tabindex="4" accesskey="D" />
                     <input id="btnLoadPDS" style="z-index: 103; left: 0px; position: absolute; top: 180px; width: 60px;"
                         type="button" value="Load PDS" onclick="return btnLoadPDS_onclick()" tabindex="8" accesskey="L" />
                     <input id="btnHelp" style="z-index: 112; left: 321px; width: 76px; position: absolute;
                         top: 229px; height: 24px;" type="button" value="Help" onclick="return btnHelp_onclick()" tabindex="7" accesskey="H" />
                      <input id="btnFuncScUp" style="z-index: 108; left: 70px; width: 24px; position: absolute;
                         top: 101px" type="button" value="^" onclick="return btnFuncScUp_onclick()" tabindex="5" />
                     <table id="tblFuncs" border=1 width=80% style="z-index: 110; left: 113px; width: 1%; position: absolute; top: 55px">
                        <thead>
                            <tr><th style="height: 42px; visibility: hidden">POS</th><th style="height: 42px">Name</th><th style="height: 42px">Mode</th><th style="height: 42px">Description</th></tr>
                        </thead>
                        <tbody>
                        </tbody>
                     </table>
                     <input id="txbLibDesc" style="z-index: 111; left: 111px; width: 282px; position: absolute;
                         top: 8px" type="text" tabindex="1" />
                 </SPAN></TD>
  		  	  <TD VALIGN="TOP" style="height: 244px">
  				&nbsp;
  		  	  </TD>
 		  	 </TR>
 			 <TR>
  			  <TD VALIGN="TOP" HEIGHT="100%" COLSPAN="7">
  				&nbsp;
  			  </TD>
 			 </TR>
		 	</TABLE>
			
	   	  <!--CLOSE OF CONTENT//-->
		  </TD>
		 </TR>
		 <TR VALIGN="BOTTOM">
		  <TD HEIGHT="48">
	   	  <!--OPEN OF BUTTON HTML//-->
		  
		  	<TABLE HEIGHT="48" BORDER="0" CELLPADDING="0" CELLSPACING="0">
			<COL WIDTH="12"><COL><COL WIDTH="75"><COL WIDTH="4"><COL WIDTH="75"><COL WIDTH="4"><COL WIDTH="75"><COL WIDTH="12">
			 <TR>
  			  <TD VALIGN="TOP" CLASS="RULE" COLSPAN="8" HEIGHT="2">
				<TABLE BORDER="0" WIDTH="100%" HEIGHT="1" CELLPADDING="0" CELLSPACING="0">
  	 			 <TR VALIGN="TOP">
  	  			  <TD HEIGHT="1" WIDTH="100%" BGCOLOR="BUTTONSHADOW"><IMG SRC="../../Images/spacer.gif" HEIGHT="1" WIDTH="1" ALT=""></TD>
  	  			  <TD HEIGHT="1" WIDTH="1" BGCOLOR="WINDOW"><IMG SRC="../../Images/spacer.gif" HEIGHT="1" WIDTH="1" ALT=""></TD>
  	 			 </TR>
				</TABLE>
  			  </TD>
 			  </TR>
 
 			  <TR>
  			  <TD VALIGN="TOP" HEIGHT="11" COLSPAN="8">
  				&nbsp;
  			  </TD>
 			 </TR>
 
 			<TR>
  			  <TD VALIGN="MIDDLE" HEIGHT="23" WIDTH="12">
  				&nbsp;
  			  </TD>
  			  <TD VALIGN="TOP" HEIGHT="23">
  				&nbsp;
  			  </TD>
  			  <TD VALIGN="MIDDLE" HEIGHT="23" WIDTH="75">
  				<BUTTON CLASS="BUTTONS" ID="FinishBtn" ACCESSKEY="F" onClick="OnFinish(document);"><U>F</U>inish</BUTTON>
  			  </TD>
  			  <TD VALIGN="MIDDLE" HEIGHT="23" WIDTH="4">
  				&nbsp;
  			  </TD>
  			  <TD VALIGN="MIDDLE" HEIGHT="23" WIDTH="75">
  				<BUTTON CLASS="BUTTONS" ID="CancelBtn" ACCESSKEY="C" onClick="window.external.Finish(document, 'cancel');"><U>C</U>ancel</BUTTON>
  			  </TD>
  			  <TD VALIGN="MIDDLE" HEIGHT="23" WIDTH="4">
  				&nbsp;
  			  </TD>
  			  <TD VALIGN="MIDDLE" HEIGHT="23" WIDTH="75">
  				<BUTTON CLASS="BUTTONS" ID="HelpBtn" ACCESSKEY="H" onClick="window.external.OnHelp('vc.appwiz.custom.overview');"><U>H</U>elp</BUTTON>
  			  </TD>
  			  <TD VALIGN="MIDDLE" HEIGHT="23" WIDTH="12">
  				&nbsp;
  			  </TD>
 			 </TR>
 
 			 <TR>
  			  <TD VALIGN="TOP" HEIGHT="12" COLSPAN="8">
  				&nbsp;
  			  </TD>
 			 </TR>
			</TABLE>
			
	   	  <!--CLOSE OF BUTTON HTML//-->
		  </TD>
		 </TR>
		</TABLE>
	
  	<!--CLOSE OF NAVIGATION, CONTENT, AND BUTTON TABLES//-->
 	</TD>
  </TR>
</TABLE>


</BODY>
</HTML>

<SCRIPT LANGUAGE="JSCRIPT">

var tab_array = new Array();
tab_array[0] = Default;

// parameter/property indexes
var lNextFuncIndex = 1;         // used for name of next func added
var lSelFuncIndex = -1;         // selected func (0-based)
var lTopFuncIndex = 0;          // top displayed func (0-based)

// length constants
var NAME_LENGTH = 15;
var DEFVAL_LENGTH = 20;
var DESC_LENGTH = 12;

var MAX_PROJNAME_LEN = 16;
var FUNC_ROWCNT = 5;            // number of visible rows in function list

// days of the week
var aDays = new Array("Sunday", "Monday", "Tuesday", "Wednesday",
    "Thursday", "Friday", "Saturday");

// months of the year
var aMonths = new Array("January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December");

// ActiveX objects
var g_oFuncDlg;   // VB function dialog
var g_oSD;        // scripting dictionary

// global variables
var eOperation;
var g_sLocOfRIncls;
var aFunctions = new Array();
var g_oWizard;

function SetUpDebug()
{
    try
    {
        g_oWizard = wizard;
    }
    catch(e)
    {
        g_oWizard = window.external;
    }
    
    g_oWizard.ReportError("Break Me!")
}
// This is an example of a function which initializes the page
//
function InitDocument(document)
{
    var i;
    var sProjectName;
    var sAbsPath;
    
	setDirection();
	
	if (window.external.FindSymbol('DOCUMENT_FIRST_LOAD'))
	{
		// This function sets the default symbols based 
		// on the values specified in the SYMBOL tags above
		//
		window.external.SetDefaults(document);
		
		// create activeX object (will allow access to OLH)
        g_oFuncDlg = new ActiveXObject("MKFP8DlgsR.clsWizDlgs");
        
        // initialize globals
        g_sLocOfRIncls = "";
		
		// check length of project name
        sProjectName = window.external.FindSymbol("PROJECT_NAME");
        if(sProjectName.length > MAX_PROJNAME_LEN)
        {
            window.alert("Project name '" + sProjectName + "' exceeds the maximum length of 16.  You must cancel this dialog and choose a shorter name.");
            
            // disable all controls so that user will be forced to rename project
	        btnAddFunc.disabled = true;
	        btnEditFunc.disabled = true;
	        btnDelFunc.disabled = true;
	        
	        // no need to continue
	        return;
        }
        else
	    {
	        // no functions yet...disable Edit/Delete controls
	        btnEditFunc.disabled = true;
	        btnDelFunc.disabled = true;
	        
	        // create scripting dictionary
	        g_oSD = new ActiveXObject("Scripting.Dictionary");

	        // set up OLH
	        sAbsPath = window.external.FindSymbol('ABSOLUTE_PATH')
	        g_oFuncDlg.SetHelpFile(sAbsPath);
	    }
	}
	else
	{
	    // Currently, this code will never execute since FPWizard8 consists of only a single page.  This code
	    //  would execute if we entered this page from an adjacent one (via either 'Previous' or 'Next').
	    
	    // load aFunctions from symbol table
	    LoadFromSymbols();
	    
	    // add functions to table
	    for(i=0;i<aFunctions.length;i++)
	        AddFuncToTable(aFunctions[i], i);
	}

	// Load the document and initialize the controls 
	// with the appropriate symbol values
	//
	window.external.Load(document);
	    
    // used for debugging only
    //SetUpDebug();
}

// If the wizard has more than 1 page, this 
// function will browse to the page specified
//
function Next(document, linkto)
{
    // process all defined functions
    if(!ProcessFuncs())
        return;
    
	window.external.Next(document, linkto);
}

// This is an example of a function which
// gets called when the user clicks on 'Finish'
//
function OnFinish(document)
{
    // process all defined functions
    if(!ProcessFuncs())
        return;
	
	OnWizFinish(document);
}

</SCRIPT>
<SCRIPT ID="INCLUDE_SCRIPT" LANGUAGE="JSCRIPT"></SCRIPT>
<SCRIPT ID="INCLUDE_COMMON" LANGUAGE="JSCRIPT"></SCRIPT>
<!-- 
Common.js is a script file which contains the helper functions 
used by the wizards.  Include this line if you want to
call these functions from your html scripts.
//-->
<!--
SCRIPT element above did not allow access to Common.js.
Adding element below seems to work.
-->
<SCRIPT LANGUAGE="JavaScript" SRC="..\..\Scripts\1033\Common.js"></SCRIPT>
<SCRIPT LANGUAGE="JavaScript" SRC="..\..\Scripts\1033\FPCodeStrs.js"></SCRIPT>
<SCRIPT>
	var strPath = window.external.FindSymbol("PRODUCT_INSTALLATION_DIR");
	strPath += "VCWizards/";
	strPath += window.external.GetHostLocale();
	var strScriptPath = strPath + "/Script.js";
	var strCommonPath = strPath + "/Common.js";
	document.scripts("INCLUDE_SCRIPT").src = strScriptPath;
	document.scripts("INCLUDE_COMMON").src = strCommonPath;

/*--------------------------------------------------------------------------------------
FUNCTION:   LoadDictionary()
INPUTS:     none
RETURNS:    none
CREATED:    5/15/08

This function loads the specified function into the scripting dictionary.  In addition,
it loads all function names (except the current one), to be used to ensure the name of
the function being added/edited does not conflict with existing function names.
--------------------------------------------------------------------------------------*/
function LoadDictionary(oFunc)
{
    var i;
    var oParam;
    var oProp;
    var bAdd;
    var bIgnore;
    
    // initialize
    bAdd = (eOperation==opAdd);
    
    // clear dictionary
    g_oSD.RemoveAll();
    
    // add operation type
    g_oSD.Add("Operation", eOperation);
    
    // load function
    g_oSD.Add("FuncName", oFunc.name);
    g_oSD.Add("FuncDesc", oFunc.description);
    g_oSD.Add("Mode", oFunc.mode);
    g_oSD.Add("FPType", oFunc.fpType);
    g_oSD.Add("RepCnt", oFunc.lRepCnt);
    g_oSD.Add("IsOrderSig", oFunc.isOrderSig);
    
    // add parameter information
    for(i=1;i<=oFunc.params.length;i++)
    {
        // get access to parameter
        oParam = oFunc.params[i-1];
        
        // load parameter information
        g_oSD.Add("ParamName" + i, oParam.name);
        g_oSD.Add("ParamType" + i, oParam.paramType);
        g_oSD.Add("DataType" + i, oParam.dataType);
        g_oSD.Add("IOType" + i, oParam.ioType);
    }
    g_oSD.Add("ParamCount", oFunc.params.length);
    
    // add property information
    for(i=1;i<=oFunc.props.length;i++)
    {
        // get access to property
        oProp = oFunc.props[i-1];
        
        // load property information
        g_oSD.Add("PropName" + i, oProp.name);
        g_oSD.Add("PropType" + i, oProp.propType);
        g_oSD.Add("DefValue" + i, oProp.defValue);
        g_oSD.Add("PropDesc" + i, oProp.description);
    }
    g_oSD.Add("PropCount", oFunc.props.length);
    
    // load names of all functions except current one (used to validate current function name)
    if(lSelFuncIndex >= 0)
    {
        for(i=1;i<=aFunctions.length;i++)
        {
            // ignore name if it is the function we are adding or editing
            bIgnore = ((bAdd && (i==aFunctions.length)) || (!bAdd && (i==lSelFuncIndex + 1)));
            if(!bIgnore)
                g_oSD.Add("FuncName" + i, aFunctions[i-1].name);
            else
                // set name to empty string, so that it will not conflict with itself
                g_oSD.Add("FuncName" + i, "");
        }
        
        // add function count
        g_oSD.Add("FuncCount", aFunctions.length);
    }
    else
        // no selected function...only true if adding first function...therefore, no need to
        //  check for duplicates...set function count to zero
        g_oSD.Add("FuncCount", 0);
}

/*--------------------------------------------------------------------------------------
FUNCTION:   LoadFunction()
INPUTS:     oFunc       function to load
RETURNS:    none
CREATED:    5/19/08

This function loads the function currently defined in the dictionary into the specfied
function object.  Global R information is also loaded.
--------------------------------------------------------------------------------------*/
function LoadFunction(oFunc) {
    var i;
    var lCount;
    var oParam, oProp;
    
    // load global information
    g_sLocOfRIncls = g_oSD.Item("LocOfRIncls");
    
    // clear function object
    while(oFunc.params.length > 0)
        oFunc.params.pop();
    while(oFunc.props.length > 0)
        oFunc.props.pop();
        
    // initialize function object with updated information
    oFunc.name = g_oSD.Item("FuncName");
    oFunc.description = g_oSD.Item("FuncDesc");
    oFunc.mode = g_oSD.Item("Mode");
    oFunc.fpType = g_oSD.Item("FPType");
    oFunc.lRepCnt = g_oSD.Item("RepCnt");
    oFunc.isOrderSig = g_oSD.Item("IsOrderSig");
    oFunc.bRFunc = false;
    
    // load function parameters
    lCount = g_oSD.Item("ParamCount");
    for(i=1;i<=lCount;i++)
    {
        oParam = new Object;
        oParam.name = g_oSD.Item("ParamName" + i);
        oParam.paramType = g_oSD.Item("ParamType" + i);
        oParam.dataType = g_oSD.Item("DataType" + i);
        oParam.ioType = g_oSD.Item("IOType" + i);
        
        // add new parameter object to list
        oFunc.params.push(oParam);
    }
    
    // load function properties
    lCount = g_oSD.Item("PropCount");
    for(i=1;i<=lCount;i++)
    {
        oProp = new Object;
        oProp.name = g_oSD.Item("PropName" + i);
        oProp.propType = g_oSD.Item("PropType" + i);
        oProp.defValue = g_oSD.Item("DefValue" + i);
        oProp.description = g_oSD.Item("PropDesc" + i);
        
        // check for R function
        if(oProp.name==RSCRIPT_PROPNAME)
            oFunc.bRFunc = true;
        
        // add new property object to list
        oFunc.props.push(oProp);
    }
}

/*--------------------------------------------------------------------------------------
FUNCTION:   LoadFunctions()
INPUTS:     none
RETURNS:    none
CREATED:    10/6/10

This function loads the all functions currently defined in the dictionary into the
global array of functions.
--------------------------------------------------------------------------------------*/
function LoadFunctions() {
    var i, j;
    var lFCount, lPCount;
    var oFunc, oParam, oProp;
    
    // load global information
    g_sLocOfRIncls = g_oSD.Item("LocOfRIncls");
    
    // load functions
    lFCount = g_oSD.Item("FuncCount");
    for(i=1;i<=lFCount;i++)
    {
        // allocate and initialize new function object
        oFunc = new Object;
        oFunc.params = new Array();
        oFunc.props = new Array();
    
        // add new function object to end of functions array
        aFunctions[aFunctions.length] = oFunc;
            
        // initialize function object with updated information
        oFunc.name = g_oSD.Item("FuncName" + i);
        oFunc.description = g_oSD.Item("FuncDesc" + i);
        oFunc.mode = g_oSD.Item("Mode" + i);
        oFunc.fpType = g_oSD.Item("FPType" + i);
        oFunc.lRepCnt = g_oSD.Item("RepCnt" + i);
        oFunc.isOrderSig = g_oSD.Item("IsOrderSig" + i);
        oFunc.bRFunc = false;
        
        // load function parameters
        lPCount = g_oSD.Item("ParamCount" + i);
        for(j=1;j<=lPCount;j++)
        {
            oParam = new Object;
            oParam.name = g_oSD.Item("ParamName" + i + "_" + j);
            oParam.paramType = g_oSD.Item("ParamType" + i + "_" + j);
            oParam.dataType = g_oSD.Item("DataType" + i + "_" + j);
            oParam.ioType = g_oSD.Item("IOType" + i + "_" + j);
            
            // add new parameter object to list
            oFunc.params.push(oParam);
        }
        
        // load function properties
        lPCount = g_oSD.Item("PropCount" + i);
        for(j=1;j<=lPCount;j++)
        {
            oProp = new Object;
            oProp.name = g_oSD.Item("PropName" + i + "_" + j);
            oProp.propType = g_oSD.Item("PropType" + i + "_" + j);
            oProp.defValue = g_oSD.Item("DefValue" + i + "_" + j);
            oProp.description = g_oSD.Item("PropDesc" + i + "_" + j);
            
            // check for R function
            if(oProp.name==RSCRIPT_PROPNAME)
                oFunc.bRFunc = true;
                
            // add new property object to list
            oFunc.props.push(oProp);
        }
        
        // increment function types count
        aFPCounts[oFunc.fpType]++;
    }
}

/*--------------------------------------------------------------------------------------
FUNCTION:   AddFuncToTable()
INPUTS:     oFunc           function to add
            lNextSelIndex   next value for lSelFuncIndex
RETURNS:    none
CREATED:    8/28/08

This function adds the specified function to the end of the function table.  Any
scrolling of the table caused by the additional function is also handled.
--------------------------------------------------------------------------------------*/
function AddFuncToTable(oFunc, lNextSelIndex)
{
    var i;
    var lHiddenFuncs;
    var oRow;
    var aRows;
    var aCells;
    var oPosCell;
    var oNameCell;
    var oModeCell;
    var oDescCell;
        
    // access rows collection of function table
    aRows = tblFuncs.rows;
    
    if(lSelFuncIndex >= 0)
        // not first func...deselect current func
        aRows(lSelFuncIndex + 1).cells(0).innerText = CELL_DESELECT;
    
    // set current index
    lSelFuncIndex = lNextSelIndex;
    
    // check if scrolling is necessary
    if(aRows.length > FUNC_ROWCNT)
    {
        // calculate number of hidden rows at bottom of list
        lHiddenRows = aRows.length - (lTopFuncIndex + 1) - FUNC_ROWCNT;
        
        // reveal all hidden bottom rows, while hiding an equal number of top rows
        for(i=0;i<lHiddenRows;i++)
        {
            aRows(lTopFuncIndex + 1).style.display = "none";
            lTopFuncIndex++;
            aRows(aRows.length - 1 - i).style.display = "";
        }
        
        // hide one additional top row, to make room for new row at bottom
        aRows(lTopFuncIndex + 1).style.display = "none";
        lTopFuncIndex++;
    }
    
    // insert new row at end of table
    oRow = tblFuncs.insertRow();
    
    // access new row's cells collection
    aCells = oRow.cells;
    
    // insert cells on new row
    oPosCell = aRows(oRow.rowIndex).insertCell(aCells.length);
    oNameCell = aRows(oRow.rowIndex).insertCell(aCells.length);
    oModeCell = aRows(oRow.rowIndex).insertCell(aCells.length);
    oDescCell = aRows(oRow.rowIndex).insertCell(aCells.length);
    
    // initialize new cells
    oPosCell.innerText = CELL_SELECT;
    oNameCell.innerText = Truncate(oFunc.name, NAME_LENGTH);
    oModeCell.innerText = aModeTypes[oFunc.mode];
    oDescCell.innerText = Truncate(oFunc.description, DESC_LENGTH);
    oDescCell.noWrap = true;
    
    // update func index
    lNextFuncIndex++;
}

/*--------------------------------------------------------------------------------------
FUNCTION:   btnAddFunc_onclick()
INPUTS:     none
RETURNS:    none
CREATED:    10/12/07

This function adds a new function to the function array.
--------------------------------------------------------------------------------------*/
function btnAddFunc_onclick() {
    var oFunc;
    
    // allocate and initialize new function object
    oFunc = new Object;
    oFunc.name = "function" + lNextFuncIndex;
    oFunc.description = "";
    oFunc.mode = fmSimple;
    oFunc.fpType = ftSimple;
    oFunc.lRepCnt = 0;
    oFunc.isOrderSig = boFalse;
    oFunc.bRFunc = false;
    oFunc.params = new Array();
    oFunc.props = new Array();
    
    // add new function object to end of functions array
    aFunctions[aFunctions.length] = oFunc;
   
    // set operation type
    eOperation = opAdd;
    
    // load function into scripting dictionary
    LoadDictionary(oFunc);
    
    // open add function dialog
    g_oFuncDlg.DisplayDialog(g_oSD);
    if(g_oSD.Exists("OK"))
    {
        // load function information from dictionary
        LoadFunction(oFunc);
        
        // increment function types count
        aFPCounts[oFunc.fpType]++;
        
        // insert new function at end of table
        AddFuncToTable(oFunc, aFunctions.length - 1);
        
        // enable edit & delete buttons
        btnEditFunc.disabled = false;
        btnDelFunc.disabled = false;
    }
    else
    {
        // add operation was canceled...pop new object off array
        aFunctions.pop();
    }
}

/*--------------------------------------------------------------------------------------
FUNCTION:   btnEditFunc_onclick()
INPUTS:     none
RETURNS:    none
CREATED:    10/12/07

This function edits the currently selected function.
--------------------------------------------------------------------------------------*/
function btnEditFunc_onclick() {
    var oFunc;
    var eFPType;
    
    // access current function
    oFunc = aFunctions[lSelFuncIndex];
        
    // save current FP type
    eFPType = oFunc.fpType;
    
    // set operation type
    eOperation = opEdit;
    
    // load function into scripting dictionary
    LoadDictionary(oFunc);
    
    // open add function dialog
    g_oFuncDlg.DisplayDialog(g_oSD);
    if(g_oSD.Exists("OK"))
    {
        // load function information from dictionary
        LoadFunction(oFunc);
        
        // access rows collection of function table
        aRows = tblFuncs.rows;
        
        // access current row's cells collection
        aCells = aRows(lSelFuncIndex + 1).cells;
        
        // update cells
        aCells(1).innerText = Truncate(oFunc.name, NAME_LENGTH);
        aCells(2).innerText = aModeTypes[oFunc.mode];
        aCells(3).innerText = Truncate(oFunc.description, DESC_LENGTH);
        
        // check if FP type changed
        if(oFunc.fpType != eFPType)
        {
            // FP type changed...need to update counts
            aFPCounts[eFPType]--;
            aFPCounts[oFunc.fpType]++;
        }
    }
    //else...edit was cancelled...do nothing
}

/*--------------------------------------------------------------------------------------
FUNCTION:   btnDelFunc_onclick()
INPUTS:     none
RETURNS:    none
CREATED:    10/17/07

This function deletes the currently selected function.
--------------------------------------------------------------------------------------*/
function btnDelFunc_onclick() {
    if(lSelFuncIndex >= 0)
    {
        // confirm delete
        if(window.confirm("Do you wish to delete '" + aFunctions[lSelFuncIndex].name + "'?"))
        {
            // decrement function types count
            aFPCounts[aFunctions[lSelFuncIndex].fpType]--;
            
            // delete from funcs array
            aFunctions.splice(lSelFuncIndex, 1);
            
            // delete from func table rows
            tblFuncs.deleteRow(lSelFuncIndex + 1);
            
            // check func count
            if(aFunctions.length > 0)
            {
                // at least one func left...update selected index
                if(lSelFuncIndex == aFunctions.length)
                    // just deleted last func...select previous func
                    lSelFuncIndex--;
                //else...selected index now points to next func...do nothing
                
                // deleted func leaves room for another row...check if
                // there are any hidden rows below
                if(aFunctions.length - lTopFuncIndex > FUNC_ROWCNT - 1)
                    // need to unhide new bottom row
                    tblFuncs.rows(lTopFuncIndex + FUNC_ROWCNT).style.display = "";
                else
                {
                    // check if there are any hidden rows above
                    if(lTopFuncIndex > 0)
                    {
                        // need to unhide new top row
                        tblFuncs.rows(lTopFuncIndex).style.display = "";
                        
                        // update top index
                        lTopFuncIndex--;
                    }
                }
                
                // mark the selected func
                tblFuncs.rows(lSelFuncIndex + 1).cells(0).innerText = CELL_SELECT;
            }
            else
            {
                // no funcs left
                lSelFuncIndex = -1;
                btnEditFunc.disabled = true;
                btnDelFunc.disabled = true;
            }
        }
    }
    //else...no funcs...do nothing
}

/*--------------------------------------------------------------------------------------
FUNCTION:   btnLoadPDS_onclick()
INPUTS:     none
RETURNS:    none
CREATED:    10/5/10

This function loads functions from the selected PDS file.
--------------------------------------------------------------------------------------*/
function btnLoadPDS_onclick() {
    var i;
    var lPrevFuncCnt;   // # of functions prior to loading from PDS
    
    // clear dictionary
    g_oSD.RemoveAll();
    
    // load names of all functions (used to ensure function name uniqueness)
    if(aFunctions.length > 0)
    {
        for(i=1;i<=aFunctions.length;i++)
            g_oSD.Add("FuncName" + i, aFunctions[i-1].name);
    }
        
    // add function count
    g_oSD.Add("FuncCount", aFunctions.length);
    
    // open common dialog so that user can select PDS file
    g_oFuncDlg.LoadPDS(g_oSD);
    if(g_oSD.Exists("OK"))
    {
        // load all functions from dictionary
        lPrevFuncCnt = aFunctions.length;
        LoadFunctions();
        
        // insert new functions at end of table
        for(i=lPrevFuncCnt;i<aFunctions.length;i++)
            AddFuncToTable(aFunctions[i], i);
        
        // enable edit & delete buttons
        btnEditFunc.disabled = false;
        btnDelFunc.disabled = false;
    }
    //else...no functions...do nothing
}

/*--------------------------------------------------------------------------------------
FUNCTION:   btnFuncScUp_onclick()
INPUTS:     none
RETURNS:    none
CREATED:    10/17/07

This function moves the function selection marker up one, scrolling the displayed
functions, if necessary.
--------------------------------------------------------------------------------------*/
function btnFuncScUp_onclick() {
    if(lSelFuncIndex > 0)
    {
        // select previous func
        lSelFuncIndex--;
        
        // check if new selected func is displayed
        if(lSelFuncIndex < lTopFuncIndex)
        {
            // need to scroll down...hide bottom row
            tblFuncs.rows(lTopFuncIndex + FUNC_ROWCNT).style.display = "none";
            
            // unhide new top row
            tblFuncs.rows(lTopFuncIndex).style.display = "";
            
            // reset current top
            lTopFuncIndex--;
        }
        
        // deselect previous current func
        tblFuncs.rows(lSelFuncIndex + 2).cells(0).innerText = CELL_DESELECT;
        
        // select new current func
        tblFuncs.rows(lSelFuncIndex + 1).cells(0).innerText = CELL_SELECT;
    }
    //else...no funcs, or first func currently selected...do nothing
}

/*--------------------------------------------------------------------------------------
FUNCTION:   btnFuncScDown_onclick()
INPUTS:     none
RETURNS:    none
CREATED:    10/17/07

This function moves the function selection marker down one, scrolling the displayed
functions, if necessary.
--------------------------------------------------------------------------------------*/
function btnFuncScDown_onclick() {
    if((lSelFuncIndex >= 0) && (lSelFuncIndex != aFunctions.length - 1))
    {
        // select next func
        lSelFuncIndex++;
        
        // check if new selected func is displayed
        if(lSelFuncIndex > lTopFuncIndex + FUNC_ROWCNT - 1)
        {
            // need to scroll up...hide top row
            tblFuncs.rows(lTopFuncIndex + 1).style.display = "none";
            
            // unhide new bottom row
            tblFuncs.rows(lTopFuncIndex + FUNC_ROWCNT + 1).style.display = "";
            
            // reset current top
            lTopFuncIndex++;
        }
        
        // deselect previous current func
        tblFuncs.rows(lSelFuncIndex).cells(0).innerText = CELL_DESELECT;
        
        // select new current func
        tblFuncs.rows(lSelFuncIndex + 1).cells(0).innerText = CELL_SELECT;
    }
}

/*--------------------------------------------------------------------------------------
FUNCTION:   btnHelp_onclick()
INPUTS:     none
RETURNS:    none
CREATED:    6/10/08

This function opens the "Step 1" OLH topic.
--------------------------------------------------------------------------------------*/
function btnHelp_onclick() {
    g_oFuncDlg.OpenTopic(1098);
}

</SCRIPT>